/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.src.uniandes.ecos.tsp.creditscore.jpa;

import com.src.uniandes.ecos.tsp.creditscore.entity.ClienteProducto;
import com.src.uniandes.ecos.tsp.creditscore.entity.ClienteProductoPK;
import com.src.uniandes.ecos.tsp.creditscore.jpa.exceptions.NonexistentEntityException;
import com.src.uniandes.ecos.tsp.creditscore.jpa.exceptions.PreexistingEntityException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import com.src.uniandes.ecos.tsp.creditscore.entity.Cliente;
import com.src.uniandes.ecos.tsp.creditscore.entity.EstadoObligacion;
import com.src.uniandes.ecos.tsp.creditscore.entity.Producto;
import com.src.uniandes.ecos.tsp.creditscore.entity.TipoArticulo;
import com.src.uniandes.ecos.tsp.creditscore.entity.HistorialCrediticio;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author AndhyMao
 */
public class ClienteProductoJpaController {

    public ClienteProductoJpaController() {
        emf = Persistence.createEntityManagerFactory("CreditScoreJavaLibraryEntitiesPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(ClienteProducto clienteProducto) throws PreexistingEntityException, Exception {
        if (clienteProducto.getClienteProductoPK() == null) {
            clienteProducto.setClienteProductoPK(new ClienteProductoPK());
        }
        if (clienteProducto.getHistorialCrediticioList() == null) {
            clienteProducto.setHistorialCrediticioList(new ArrayList<HistorialCrediticio>());
        }
        clienteProducto.getClienteProductoPK().setCliCodigo(clienteProducto.getCliente().getCliCodigo());
        clienteProducto.getClienteProductoPK().setProCodigo(clienteProducto.getProducto().getProCodigo());
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Cliente cliente = clienteProducto.getCliente();
            if (cliente != null) {
                cliente = em.getReference(cliente.getClass(), cliente.getCliCodigo());
                clienteProducto.setCliente(cliente);
            }
            EstadoObligacion eobCodigo = clienteProducto.getEobCodigo();
            if (eobCodigo != null) {
                eobCodigo = em.getReference(eobCodigo.getClass(), eobCodigo.getEobCodigo());
                clienteProducto.setEobCodigo(eobCodigo);
            }
            Producto producto = clienteProducto.getProducto();
            if (producto != null) {
                producto = em.getReference(producto.getClass(), producto.getProCodigo());
                clienteProducto.setProducto(producto);
            }
            TipoArticulo artCodigo = clienteProducto.getArtCodigo();
            if (artCodigo != null) {
                artCodigo = em.getReference(artCodigo.getClass(), artCodigo.getArtCodigo());
                clienteProducto.setArtCodigo(artCodigo);
            }
            List<HistorialCrediticio> attachedHistorialCrediticioList = new ArrayList<HistorialCrediticio>();
            for (HistorialCrediticio historialCrediticioListHistorialCrediticioToAttach : clienteProducto.getHistorialCrediticioList()) {
                historialCrediticioListHistorialCrediticioToAttach = em.getReference(historialCrediticioListHistorialCrediticioToAttach.getClass(), historialCrediticioListHistorialCrediticioToAttach.getHcrCodigo());
                attachedHistorialCrediticioList.add(historialCrediticioListHistorialCrediticioToAttach);
            }
            clienteProducto.setHistorialCrediticioList(attachedHistorialCrediticioList);
            em.persist(clienteProducto);
            if (cliente != null) {
                cliente.getClienteProductoList().add(clienteProducto);
                cliente = em.merge(cliente);
            }
            if (eobCodigo != null) {
                eobCodigo.getClienteProductoList().add(clienteProducto);
                eobCodigo = em.merge(eobCodigo);
            }
            if (producto != null) {
                producto.getClienteProductoList().add(clienteProducto);
                producto = em.merge(producto);
            }
            if (artCodigo != null) {
                artCodigo.getClienteProductoList().add(clienteProducto);
                artCodigo = em.merge(artCodigo);
            }
            for (HistorialCrediticio historialCrediticioListHistorialCrediticio : clienteProducto.getHistorialCrediticioList()) {
                ClienteProducto oldClienteProductoOfHistorialCrediticioListHistorialCrediticio = historialCrediticioListHistorialCrediticio.getClienteProducto();
                historialCrediticioListHistorialCrediticio.setClienteProducto(clienteProducto);
                historialCrediticioListHistorialCrediticio = em.merge(historialCrediticioListHistorialCrediticio);
                if (oldClienteProductoOfHistorialCrediticioListHistorialCrediticio != null) {
                    oldClienteProductoOfHistorialCrediticioListHistorialCrediticio.getHistorialCrediticioList().remove(historialCrediticioListHistorialCrediticio);
                    oldClienteProductoOfHistorialCrediticioListHistorialCrediticio = em.merge(oldClienteProductoOfHistorialCrediticioListHistorialCrediticio);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findClienteProducto(clienteProducto.getClienteProductoPK()) != null) {
                throw new PreexistingEntityException("ClienteProducto " + clienteProducto + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(ClienteProducto clienteProducto) throws NonexistentEntityException, Exception {
        clienteProducto.getClienteProductoPK().setCliCodigo(clienteProducto.getCliente().getCliCodigo());
        clienteProducto.getClienteProductoPK().setProCodigo(clienteProducto.getProducto().getProCodigo());
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ClienteProducto persistentClienteProducto = em.find(ClienteProducto.class, clienteProducto.getClienteProductoPK());
            Cliente clienteOld = persistentClienteProducto.getCliente();
            Cliente clienteNew = clienteProducto.getCliente();
            EstadoObligacion eobCodigoOld = persistentClienteProducto.getEobCodigo();
            EstadoObligacion eobCodigoNew = clienteProducto.getEobCodigo();
            Producto productoOld = persistentClienteProducto.getProducto();
            Producto productoNew = clienteProducto.getProducto();
            TipoArticulo artCodigoOld = persistentClienteProducto.getArtCodigo();
            TipoArticulo artCodigoNew = clienteProducto.getArtCodigo();
            List<HistorialCrediticio> historialCrediticioListOld = persistentClienteProducto.getHistorialCrediticioList();
            List<HistorialCrediticio> historialCrediticioListNew = clienteProducto.getHistorialCrediticioList();
            if (clienteNew != null) {
                clienteNew = em.getReference(clienteNew.getClass(), clienteNew.getCliCodigo());
                clienteProducto.setCliente(clienteNew);
            }
            if (eobCodigoNew != null) {
                eobCodigoNew = em.getReference(eobCodigoNew.getClass(), eobCodigoNew.getEobCodigo());
                clienteProducto.setEobCodigo(eobCodigoNew);
            }
            if (productoNew != null) {
                productoNew = em.getReference(productoNew.getClass(), productoNew.getProCodigo());
                clienteProducto.setProducto(productoNew);
            }
            if (artCodigoNew != null) {
                artCodigoNew = em.getReference(artCodigoNew.getClass(), artCodigoNew.getArtCodigo());
                clienteProducto.setArtCodigo(artCodigoNew);
            }
            List<HistorialCrediticio> attachedHistorialCrediticioListNew = new ArrayList<HistorialCrediticio>();
            for (HistorialCrediticio historialCrediticioListNewHistorialCrediticioToAttach : historialCrediticioListNew) {
                historialCrediticioListNewHistorialCrediticioToAttach = em.getReference(historialCrediticioListNewHistorialCrediticioToAttach.getClass(), historialCrediticioListNewHistorialCrediticioToAttach.getHcrCodigo());
                attachedHistorialCrediticioListNew.add(historialCrediticioListNewHistorialCrediticioToAttach);
            }
            historialCrediticioListNew = attachedHistorialCrediticioListNew;
            clienteProducto.setHistorialCrediticioList(historialCrediticioListNew);
            clienteProducto = em.merge(clienteProducto);
            if (clienteOld != null && !clienteOld.equals(clienteNew)) {
                clienteOld.getClienteProductoList().remove(clienteProducto);
                clienteOld = em.merge(clienteOld);
            }
            if (clienteNew != null && !clienteNew.equals(clienteOld)) {
                clienteNew.getClienteProductoList().add(clienteProducto);
                clienteNew = em.merge(clienteNew);
            }
            if (eobCodigoOld != null && !eobCodigoOld.equals(eobCodigoNew)) {
                eobCodigoOld.getClienteProductoList().remove(clienteProducto);
                eobCodigoOld = em.merge(eobCodigoOld);
            }
            if (eobCodigoNew != null && !eobCodigoNew.equals(eobCodigoOld)) {
                eobCodigoNew.getClienteProductoList().add(clienteProducto);
                eobCodigoNew = em.merge(eobCodigoNew);
            }
            if (productoOld != null && !productoOld.equals(productoNew)) {
                productoOld.getClienteProductoList().remove(clienteProducto);
                productoOld = em.merge(productoOld);
            }
            if (productoNew != null && !productoNew.equals(productoOld)) {
                productoNew.getClienteProductoList().add(clienteProducto);
                productoNew = em.merge(productoNew);
            }
            if (artCodigoOld != null && !artCodigoOld.equals(artCodigoNew)) {
                artCodigoOld.getClienteProductoList().remove(clienteProducto);
                artCodigoOld = em.merge(artCodigoOld);
            }
            if (artCodigoNew != null && !artCodigoNew.equals(artCodigoOld)) {
                artCodigoNew.getClienteProductoList().add(clienteProducto);
                artCodigoNew = em.merge(artCodigoNew);
            }
            for (HistorialCrediticio historialCrediticioListOldHistorialCrediticio : historialCrediticioListOld) {
                if (!historialCrediticioListNew.contains(historialCrediticioListOldHistorialCrediticio)) {
                    historialCrediticioListOldHistorialCrediticio.setClienteProducto(null);
                    historialCrediticioListOldHistorialCrediticio = em.merge(historialCrediticioListOldHistorialCrediticio);
                }
            }
            for (HistorialCrediticio historialCrediticioListNewHistorialCrediticio : historialCrediticioListNew) {
                if (!historialCrediticioListOld.contains(historialCrediticioListNewHistorialCrediticio)) {
                    ClienteProducto oldClienteProductoOfHistorialCrediticioListNewHistorialCrediticio = historialCrediticioListNewHistorialCrediticio.getClienteProducto();
                    historialCrediticioListNewHistorialCrediticio.setClienteProducto(clienteProducto);
                    historialCrediticioListNewHistorialCrediticio = em.merge(historialCrediticioListNewHistorialCrediticio);
                    if (oldClienteProductoOfHistorialCrediticioListNewHistorialCrediticio != null && !oldClienteProductoOfHistorialCrediticioListNewHistorialCrediticio.equals(clienteProducto)) {
                        oldClienteProductoOfHistorialCrediticioListNewHistorialCrediticio.getHistorialCrediticioList().remove(historialCrediticioListNewHistorialCrediticio);
                        oldClienteProductoOfHistorialCrediticioListNewHistorialCrediticio = em.merge(oldClienteProductoOfHistorialCrediticioListNewHistorialCrediticio);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                ClienteProductoPK id = clienteProducto.getClienteProductoPK();
                if (findClienteProducto(id) == null) {
                    throw new NonexistentEntityException("The clienteProducto with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(ClienteProductoPK id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            ClienteProducto clienteProducto;
            try {
                clienteProducto = em.getReference(ClienteProducto.class, id);
                clienteProducto.getClienteProductoPK();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The clienteProducto with id " + id + " no longer exists.", enfe);
            }
            Cliente cliente = clienteProducto.getCliente();
            if (cliente != null) {
                cliente.getClienteProductoList().remove(clienteProducto);
                cliente = em.merge(cliente);
            }
            EstadoObligacion eobCodigo = clienteProducto.getEobCodigo();
            if (eobCodigo != null) {
                eobCodigo.getClienteProductoList().remove(clienteProducto);
                eobCodigo = em.merge(eobCodigo);
            }
            Producto producto = clienteProducto.getProducto();
            if (producto != null) {
                producto.getClienteProductoList().remove(clienteProducto);
                producto = em.merge(producto);
            }
            TipoArticulo artCodigo = clienteProducto.getArtCodigo();
            if (artCodigo != null) {
                artCodigo.getClienteProductoList().remove(clienteProducto);
                artCodigo = em.merge(artCodigo);
            }
            List<HistorialCrediticio> historialCrediticioList = clienteProducto.getHistorialCrediticioList();
            for (HistorialCrediticio historialCrediticioListHistorialCrediticio : historialCrediticioList) {
                historialCrediticioListHistorialCrediticio.setClienteProducto(null);
                historialCrediticioListHistorialCrediticio = em.merge(historialCrediticioListHistorialCrediticio);
            }
            em.remove(clienteProducto);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<ClienteProducto> findClienteProductoEntities() {
        return findClienteProductoEntities(true, -1, -1);
    }

    public List<ClienteProducto> findClienteProductoEntities(int maxResults, int firstResult) {
        return findClienteProductoEntities(false, maxResults, firstResult);
    }

    private List<ClienteProducto> findClienteProductoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from ClienteProducto as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public ClienteProducto findClienteProducto(ClienteProductoPK id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(ClienteProducto.class, id);
        } finally {
            em.close();
        }
    }

    public int getClienteProductoCount() {
        EntityManager em = getEntityManager();
        try {
            return ((Long) em.createQuery("select count(o) from ClienteProducto as o").getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }


    public List<ClienteProducto> findClienteProductoEntities(Integer cliCodigo) {
        List<ClienteProducto> result = new ArrayList<ClienteProducto>();
        EntityManager em = getEntityManager();
        StringBuffer sqlSentence = new StringBuffer();
        sqlSentence.append(" select cliPro from ClienteProducto as cliPro");
        sqlSentence.append(" where cliPro.cliente.cliCodigo = ?1");
        Query query = em.createQuery(sqlSentence.toString());
        query.setParameter(1, cliCodigo);
        result = query.getResultList();
        return result;
    }
}
